﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Net;
using System.IO;

namespace VidoopSecure
{
    /// <summary>
    /// VidoopSecure ImageShield service.
    /// </summary>
    public class ImageShieldService : Service
    {
        /// <summary>
        /// Creates an <see cref="VidoopSecure.ImageShieldService" /> object.
        /// </summary>
        /// <param name="manager">The <see cref="VidoopSecure.VSManager /> used
        /// to perform operations with this service.</param>
        /// <param name="site">The <see cref="VidoopSecure.Site" /> associated with
        /// this service.</param>
        /// <param name="apiBase">The base URL to be used for accessing services.</param>
        public ImageShieldService(VSManager manager, Site site, string apiBase)
            : base(manager, site, apiBase)
        {
        } 


        /// <summary>
        /// Request that a new Image Shield be generated.
        /// </summary>
        /// <param name="args">A <see cref="System.Collections.Generic.Dictionary" />
        /// containing the properties of the requested Image Shield.</param>
        /// <returns>An <see cref="VidoopSecure.ImageShield" /> object.</returns>
        /// <exception cref="VidoopSecure.VidoopSecureException">If the 
        /// VidoopSecure web service does not return a 201 HTTP status code,
        /// this exception will be thrown.
        /// </exception>
        /// <seealso cref="VidoopSecure" />
        public ImageShield NewImageShield(int length, bool orderMatters, 
            int width, int height, string imageCodeColor, string userId, 
            string bundle) 
        { 
            string apiUrl = this.CreateRequestUrl("/customers/" + this.Site.CustomerId + "/sites/" + this.Site.SiteName + "/services/imageshield");

            string credentials = this.Site.Username + Util.CREDENTIALS_SEPARATOR + this.Site.Password;

            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("imageshield_length", length.ToString());
            parameters.Add("order_matter", orderMatters.ToString());
            parameters.Add("width", width.ToString());
            parameters.Add("height", height.ToString());
            parameters.Add("image_code_color", imageCodeColor.ToString());
            parameters.Add("user_id", userId);
            parameters.Add("bundle", bundle);

            HttpProxy proxy = this.Manager.ApiCall(apiUrl, "POST", parameters, credentials);

            if (proxy.StatusCode != (int)HttpStatus.Created)
                throw new VidoopSecureException(proxy.StatusCode, "Failed to create a new ImageShield.");
            else
            {
                Stream stream = proxy.Response.GetResponseStream();

                ImageShield shield = ImageShield.FromXml(stream);
                proxy.Close();
                return shield;
            }
        }

        /// <summary>
        /// Get an ImageShield by ID.
        /// </summary>
        /// <param name="id">The identifier of the ImageShield to be retrieved.</param>
        /// <returns>An <see cref="VidoopSecure.ImageShield" /> object.</returns>
        /// <exception cref="VidoopSecure.VidoopSecureException">If the 
        /// VidoopSecure web service does not return a 201 HTTP status code,
        /// this exception will be thrown.
        /// </exception>
        /// <seealso cref="VidoopSecure" />       
        public ImageShield GetImageShield(string id) 
        {
            ImageShield shield = null;

            string apiUrl = this.CreateRequestUrl("/imageshields/" + id);

            string credentials = this.Site.Username + Util.CREDENTIALS_SEPARATOR + this.Site.Password;
            
            HttpProxy proxy = this.Manager.ApiCall(apiUrl, "GET", null, credentials);
            if (proxy.StatusCode == (int)HttpStatusCode.OK)
            {
                shield = ImageShield.FromXml(proxy.Response.GetResponseStream());
                proxy.Close();
                return shield;
            }
            else
            {
                proxy.Close();
                throw new VidoopSecureException(proxy.StatusCode, string.Format("Failed to retrieve ImageShield whose ID is {0}", id));
            }
        }

        /// <summary>
        /// Verify the code for an ImageShield.
        /// </summary>
        /// <param name="id">ImageShield Id</param>
        /// <param name="code">Code to test the ImageShield</param>
        /// <returns><typeparamref name="bool"/> indicating whether the code
        /// part of the solution to the ImageShield.</returns>
        /// <seealso cref="VidoopSecure" />
        public bool VerifyCode(string id, string code) 
        {
            string apiUrl = this.CreateRequestUrl("/imageshields/" + id);

            Dictionary<string,string> parameters = new Dictionary<string,string>
            {
                { "code", code }
            };
          
            string credentials = this.Site.Username + Util.CREDENTIALS_SEPARATOR + this.Site.Password;
            
            HttpProxy proxy = this.Manager.ApiCall(apiUrl, "POST", parameters, null);
            bool result = proxy.StatusCode == (int)HttpStatusCode.OK;
            proxy.Close();

            return result;
        }
    }
    
}
